package com.cortex.pineapple.view;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;

import android.content.Context;
import android.content.res.Configuration;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;

import com.cortex.pineapple.R;
import com.cortex.pineapple.adapters.CompositeSourceAdapter;
import com.cortex.pineapple.adapters.CompositeSourceAdapter.OnSelectedSourcesChangedListener;
import com.cortex.pineapple.fetch.ResponseData;
import com.cortex.pineapple.fetch.RequestData.CATEGORY_FILTER_TYPE;
import com.cortex.pineapple.fetch.RequestData.FILTER_TYPE;
import com.cortex.pineapple.fetch.RequestData.SOURCE_TYPE;
import com.cortex.pineapple.utilities.HolderData;

public class CategoriesFiltersView extends HorizontalScrollView 
implements OnClickListener,SaveState{

	private OnSelectedCategoryFilterListener onSelectedCategoryFilterListener;
	private OnSourcesChangedListener onSelectedSourcesListener;
	private FrameLayout web,images,videos,news,composite;
	private ImageView webImage,imagesImage,videosImage,newsImage,compositeImage;
	private TextView webText,imagesText,videosText,newsText,compositeText;
	private View webLine,imagesLine,videosLine,newsLine,compositeLine;
	private CATEGORY_FILTER_TYPE selectedFilter = CATEGORY_FILTER_TYPE.WEB;
	private CATEGORY_FILTER_TYPE lastSelectedFilter;
	private Set<SOURCE_TYPE> sourcesType;
	private PopupWindow popupSources;
	private boolean isPopupSourcesOpend = false;
	private HolderData holderData = HolderData.getInstance();
	private static final String SELECTED_FILTER = "selectedFilter";
	private static final String LAST_SELECTED_FILTER = "lastSelectedFilter";
	private static final String SELECTED_SOURCES = "selectedSources";
	private static final String POPUP_SOURCES_OPEND = "popupSourcesOpend";
	private static final String POPUP_SOURCES_WIDTH = "popupSourcesWidth";



	public CategoriesFiltersView(Context context) {
		super(context);
		init();
	}
	public CategoriesFiltersView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}
	public CategoriesFiltersView(Context context, AttributeSet attrs,int style) {
		super(context, attrs,style);
		init();
	}
	@Override
	protected void onAttachedToWindow() {
		super.onAttachedToWindow();
		if(isPopupSourcesOpend){
			int width = (Integer) holderData.getData(POPUP_SOURCES_WIDTH);
			getPopupSources().setWidth(width);
			getPopupSources().showAsDropDown(composite);
		}
	}
	private void init(){
		LayoutInflater.from(getContext()).inflate(R.layout.view_categories_filters, this);
		web = (FrameLayout)findViewById(R.id.web);
		images = (FrameLayout)findViewById(R.id.images); 
		videos = (FrameLayout)findViewById(R.id.videos); 
		news = (FrameLayout)findViewById(R.id.news); 
		composite = (FrameLayout)findViewById(R.id.composite);

		webLine = findViewById(R.id.webLine);
		imagesLine = findViewById(R.id.imagesLine);
		videosLine = findViewById(R.id.videosLine);
		newsLine = findViewById(R.id.newsLine);
		compositeLine = findViewById(R.id.compositeLine);

		webImage = (ImageView)findViewById(R.id.webImage);
		imagesImage = (ImageView)findViewById(R.id.imagesImage);
		videosImage = (ImageView)findViewById(R.id.videosImage);
		newsImage = (ImageView)findViewById(R.id.newsImage);
		compositeImage = (ImageView)findViewById(R.id.compositeImage);

		webText = (TextView)findViewById(R.id.webText);
		imagesText = (TextView)findViewById(R.id.imagesText);
		videosText = (TextView)findViewById(R.id.videosText);
		newsText = (TextView)findViewById(R.id.newsText);
		compositeText = (TextView)findViewById(R.id.compositeText);

		initListeners();
		sourcesType = new HashSet<SOURCE_TYPE>();
		sourcesType.add(SOURCE_TYPE.WEB);
	}
	private void initListeners(){
		web.setOnClickListener(this);
		images.setOnClickListener(this);
		videos.setOnClickListener(this);
		news.setOnClickListener(this);
		composite.setOnClickListener(this);
	}
	@Override
	public void onClick(View v) {
		CATEGORY_FILTER_TYPE categoryFilter = null;
		if(v.getId() == web.getId()){
			categoryFilter = CATEGORY_FILTER_TYPE.WEB;
		}
		else if(v.getId() == images.getId()){
			categoryFilter = CATEGORY_FILTER_TYPE.IMAGES;
		}
		else if(v.getId() == videos.getId()){
			categoryFilter = CATEGORY_FILTER_TYPE.VIDEO;
		}
		else if(v.getId() == news.getId()){
			categoryFilter = CATEGORY_FILTER_TYPE.NEWS;
		}
		else if(v.getId() == composite.getId()){
			categoryFilter = CATEGORY_FILTER_TYPE.COMPOSITE;
		}
		if(lastSelectedFilter != categoryFilter){
			setSelectedCategory(categoryFilter);
		}
	}
	private void setSelectedCategory(CATEGORY_FILTER_TYPE category){
		reset();
		switch(category){
		case COMPOSITE:
			if(isShown()){
				getPopupSources().showAsDropDown(composite);
			}
			selectedFilter = CATEGORY_FILTER_TYPE.COMPOSITE;
			compositeLine.setVisibility(VISIBLE);
			compositeImage.setBackgroundResource(R.drawable.composite_turn_on);
			compositeText.setTextColor(getResources().getColor(R.color.text_on));
			return;
		case IMAGES:
			setSelectedCategory(CATEGORY_FILTER_TYPE.IMAGES,SOURCE_TYPE.IMAGES,imagesImage,imagesText,
					R.drawable.images_turn_on,imagesLine);
			break;
		case NEWS:
			setSelectedCategory(CATEGORY_FILTER_TYPE.NEWS,SOURCE_TYPE.NEWS,newsImage,newsText,
					R.drawable.news_turn_on,newsLine);
			break;
		case VIDEO:
			setSelectedCategory(CATEGORY_FILTER_TYPE.VIDEO,SOURCE_TYPE.VIDEO,videosImage,videosText,
					R.drawable.videos_turn_on,videosLine);
			break;
		case WEB:
			setSelectedCategory(CATEGORY_FILTER_TYPE.WEB,SOURCE_TYPE.WEB,webImage,webText,
					R.drawable.web_turn_on,webLine);
			break;
		default:
			break;

		}
		
		if(lastSelectedFilter != selectedFilter){
			if(onSelectedCategoryFilterListener != null){
				onSelectedCategoryFilterListener.selectedFilter(selectedFilter,new ArrayList<SOURCE_TYPE>(sourcesType));
			}
		}
		Toast.makeText(getContext(), selectedFilter.name(), Toast.LENGTH_LONG).show();

	}
	private void setSelectedCategory(CATEGORY_FILTER_TYPE categoryFilter,SOURCE_TYPE source,ImageView image,
			TextView text,int background,View line){
		selectedFilter = categoryFilter;
		sourcesType.add(source);
		line.setVisibility(VISIBLE);
		image.setImageResource(background);
		text.setTextColor(getResources().getColor(R.color.text_on));
		if(isShown() && popupSources != null){
			ListView listView = (ListView) getPopupSources().getContentView().findViewById(R.id.compositeSources);
			CompositeSourceAdapter adapter = (CompositeSourceAdapter)listView.getAdapter();
			adapter.clearSelectedSources();
		}
	}
	public void reset(){
		selectedFilter = null;
		sourcesType.clear();

		webLine.setVisibility(INVISIBLE);
		imagesLine.setVisibility(INVISIBLE);
		videosLine.setVisibility(INVISIBLE);
		newsLine.setVisibility(INVISIBLE);
		compositeLine.setVisibility(INVISIBLE);

		webImage.setImageResource(R.drawable.web_turn_off);
		imagesImage.setImageResource(R.drawable.images_turn_off);
		videosImage.setImageResource(R.drawable.videos_turn_off);
		newsImage.setImageResource(R.drawable.news_turn_off);
		compositeImage.setImageResource(R.drawable.composite_turn_off);

		int textOff = getResources().getColor(R.color.text_off);
		webText.setTextColor(textOff);
		imagesText.setTextColor(textOff);
		videosText.setTextColor(textOff);
		newsText.setTextColor(textOff);
		compositeText.setTextColor(textOff);
	}

	@Override
	public void saveState(){
		holderData.addData(SELECTED_FILTER,selectedFilter);
		holderData.addData(LAST_SELECTED_FILTER,lastSelectedFilter);
		holderData.addData(SELECTED_SOURCES,sourcesType);
		holderData.addData(POPUP_SOURCES_OPEND, getPopupSources().isShowing());
		holderData.addData(POPUP_SOURCES_WIDTH, getPopupSources().getWidth());
		getPopupSources().dismiss();
	}
	@Override
	public void restoreState(){
		selectedFilter = (CATEGORY_FILTER_TYPE) holderData.getData(SELECTED_FILTER);
		lastSelectedFilter =  (CATEGORY_FILTER_TYPE) holderData.getData(LAST_SELECTED_FILTER);
		isPopupSourcesOpend = (Boolean) holderData.getData(POPUP_SOURCES_OPEND);
		switch(selectedFilter){
		case COMPOSITE:
			onClick(composite);
			break;
		case IMAGES:
			onClick(images);
			break;
		case NEWS:
			onClick(news);
			break;
		case VIDEO:
			onClick(videos);
			break;
		case WEB:
			onClick(web);
			break;
		default:
			break;

		}
		sourcesType = (Set<SOURCE_TYPE>) holderData.getData(SELECTED_SOURCES);
	}
	private PopupWindow getPopupSources(){
		if(popupSources == null){
			LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

			//get the pop-up window i.e.  drop-down layout
			LinearLayout layout = (LinearLayout)inflater.inflate(R.layout.popup_composite_source, (ViewGroup)findViewById(R.id.PopUpView));

			//get the view to which drop-down layout is to be anchored
			popupSources = new PopupWindow(layout, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, true);

			//Pop-up window background cannot be null if we want the pop-up to listen touch events outside its window
			popupSources.setBackgroundDrawable(getResources().getDrawable(R.drawable.popup_background));

			popupSources.setTouchable(true);

			//let pop-up be informed about touch events outside its window. This  should be done before setting the content of pop-up
			popupSources.setOutsideTouchable(true);
			popupSources.setHeight(LayoutParams.WRAP_CONTENT);
			popupSources.setWidth(composite.getWidth());

			//dismiss the pop-up i.e. drop-down when touched anywhere outside the pop-up
			popupSources.setTouchInterceptor(new OnTouchListener() {

				public boolean onTouch(View v, MotionEvent event) {
					// TODO Auto-generated method stub
					if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
						popupSources.dismiss();
						return true;    				
					}
					return false;
				}
			});
			//provide the source layout for drop-down
			popupSources.setContentView(layout);

			//populate the drop-down list
			ListView compositeSources = (ListView) layout.findViewById(R.id.compositeSources);
			CompositeSourceAdapter adapter = new CompositeSourceAdapter(getContext(), 
					getResources().getStringArray(R.array.sources_arrays));
			adapter.setOnSelectedSourcesChangedListener(new OnSelectedSourcesChangedListener() {

				@Override
				public void sourcesChanged(List<String> sources,boolean isAllSelected) {
					sourcesType.clear();
					List<SOURCE_TYPE> selectedSources = SOURCE_TYPE.getSourceType(sources.toArray(new String[sources.size()]));
					sourcesType.addAll(selectedSources);
					if(isAllSelected){
						getPopupSources().dismiss();
					}
					if(onSelectedSourcesListener != null){
						onSelectedSourcesListener.selectedSource(getSelectedFilter(), selectedSources);
					}
				}
			});

			compositeSources.setAdapter(adapter);
		}
		return popupSources;
	}
	@Override
	public void setEnabled(boolean enabled) {
		super.setEnabled(enabled);
		web.setClickable(enabled);
		images.setClickable(enabled);
		videos.setClickable(enabled);
		news.setClickable(enabled);
		composite.setClickable(enabled);
	}
	public void setOnSelectedCategoryFilterListener(OnSelectedCategoryFilterListener onSelectedFilterListener) {
		this.onSelectedCategoryFilterListener = onSelectedFilterListener;
	}
	public void setOnSelectedSourcesListener(OnSourcesChangedListener onSelectedSourcesListener) {
		this.onSelectedSourcesListener = onSelectedSourcesListener;
	}
	public List<SOURCE_TYPE> getSelctedSources() {
		return new ArrayList<SOURCE_TYPE>(sourcesType);
	}
	public CATEGORY_FILTER_TYPE getSelectedFilter() {
		return selectedFilter;
	}
	public interface OnSelectedCategoryFilterListener{
		void selectedFilter(CATEGORY_FILTER_TYPE filterType,List<SOURCE_TYPE> sources);
	}
	public interface OnSourcesChangedListener{
		void selectedSource(CATEGORY_FILTER_TYPE filterType,List<SOURCE_TYPE>sources);
	}
}
